﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Globalization;

//WiiSoFree Coded by Shawn M. Crawford [sLeEpY] in 2008/09

namespace WiiRegionChanger
{
    public partial class wiisoFreeForm : Form
    {
        public wiisoFreeForm()
        {
            InitializeComponent();
        }

        
        //string openFlagString;
        string filename;
        string path;

        private void selectNewRegionComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {

            int x;
            x = selectNewRegionComboBox.SelectedIndex;

            switch (x)
            {
                case 0:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 1:
                    //JAP
                    newRegionCodeTextBox.Text = "00";
                    newRegionStringTextBox.Text = "00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 2:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 3:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 4:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 06 07 07 06 07 00 80 80 80 80 80 80 80";
                    break;

                case 5:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 0C 0C 0B 0C 0C 0E 80 80 80 80 80 80 80";
                    break;

                case 6:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 0C 0C 0B 0C 0C 00 80 80 80 80 80 80 80";
                    break;

                case 7:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 06 07 07 06 07 00 80 80 80 80 80 80 80";
                    break;

                case 8:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 9:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 52 10 0F 10 10 0F 80 80 80 80 80 80 80";
                    break;

                case 10:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 11:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 06 03 03 04 03 00 00 00 00 00 00 00 00";
                    break;

                case 12:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 13:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 14:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 15:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 00 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 16:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 06 03 03 04 03 00 80 80 80 80 80 80 80";
                    break;

                case 17:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 0C 0C 0B 0C 0C 07 80 80 80 80 80 80 80";
                    break;

                case 18:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 0C 0C 0B 0C 0C 07 80 80 80 80 80 80 80";
                    break;

                case 19:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "00 80 80 06 03 03 04 03 07 00 00 00 00 00 00 00";
                    break;

                case 20:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 12 10 0F 10 10 0E 80 80 80 80 80 80 80";
                    break;

                case 21:
                    //PAL
                    newRegionCodeTextBox.Text = "02";
                    newRegionStringTextBox.Text = "80 80 80 10 12 12 12 12 0F 80 80 80 80 80 80 80";
                    break;

                case 22:
                    //JAP
                    newRegionCodeTextBox.Text = "00";
                    newRegionStringTextBox.Text = "00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 23:
                    //JAP
                    newRegionCodeTextBox.Text = "00";
                    newRegionStringTextBox.Text = "00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 24:
                    //USA - barnyard
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 25:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 0D 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 26:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 26 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 27:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 28:
                    //JAP
                    newRegionCodeTextBox.Text = "00";
                    newRegionStringTextBox.Text = "00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 29:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2D 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 30:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 31:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 06 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 32:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 33:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 34:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 35:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2D 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 36:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 06 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 37:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 38:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 39:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 40:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 41:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0D 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 42:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 43:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 11 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 44:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 06 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 45:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 06 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 46:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 47:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 48:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 2A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 49:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "00 0D 80 00 80 80 80 80 00 00 00 00 00 00 00 00";
                    break;

                case 50:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 51:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0D 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 52:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0A 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 53:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 06 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                case 54:
                    //USA
                    newRegionCodeTextBox.Text = "01";
                    newRegionStringTextBox.Text = "80 0D 80 80 80 80 80 80 80 80 80 80 80 80 80 80";
                    break;

                default:
                    //error handling
                    newRegionCodeTextBox.Text = "??";
                    newRegionStringTextBox.Text = "????????????????????????????????";
                    break;

                    //55 total
            }

        }

        private void wiisoFreeForm_Load(object sender, EventArgs e)
        {

            changeBootSettingComboBox.Items.Add("Manual");
            changeBootSettingComboBox.Items.Add("Auto");
            changeBootSettingComboBox.SelectedIndex = 0;

            //Offsets 0x04E010 to 0x4E01F need to contain the 16 bytes from any other game in the region.
            //Offset 0x04E003 contains the region code...

            //0x04E003: 00 = NTSC JAP
            //0x04E003: 01 = NTSC USA
            //0x04E003: 02 = PAL

            selectNewRegionComboBox.Items.Add("USA - GENERIC");
            selectNewRegionComboBox.Items.Add("JAP - GENERIC");
            selectNewRegionComboBox.Items.Add("PAL - GENERIC");
            selectNewRegionComboBox.Items.Add("PAL - Super Fruit Fall");
            selectNewRegionComboBox.Items.Add("PAL - Super Monkey Ball Banana Blitz");
            selectNewRegionComboBox.Items.Add("PAL - THE LEGEND OF ZELDA TWILIGHT PRINCESS");
            selectNewRegionComboBox.Items.Add("PAL - Tony Hawks Downhill Jam");
            selectNewRegionComboBox.Items.Add("PAL - WarioWare Smooth Moves");
            selectNewRegionComboBox.Items.Add("PAL - WII PLAY");
            selectNewRegionComboBox.Items.Add("PAL - Call Of Duty 3");
            selectNewRegionComboBox.Items.Add("PAL - Cars");
            selectNewRegionComboBox.Items.Add("PAL - Open Season");
            selectNewRegionComboBox.Items.Add("PAL - Spongebob Squarepants - Creature from  Krusty Krab");
            selectNewRegionComboBox.Items.Add("PAL - GT Pro Series");
            selectNewRegionComboBox.Items.Add("PAL - Happy Feet");
            selectNewRegionComboBox.Items.Add("PAL - Ice Age 2 - The Meltdown");
            selectNewRegionComboBox.Items.Add("PAL - Monster 4x4 World Circuit");
            selectNewRegionComboBox.Items.Add("PAL - Need For Speed Carbon");
            selectNewRegionComboBox.Items.Add("PAL - Rampage Total Destruction");
            selectNewRegionComboBox.Items.Add("PAL - Rayman Raving Rabbids");
            selectNewRegionComboBox.Items.Add("PAL - Red Steel");
            selectNewRegionComboBox.Items.Add("PAL - Splinter Cell Double Agent");
            selectNewRegionComboBox.Items.Add("JAP - Bleach Shiraha Kirameku Rinbukyoku");
            selectNewRegionComboBox.Items.Add("JAP - Naruto Shippuden: Gekitou Ninja Taisen EX");
            selectNewRegionComboBox.Items.Add("USA - Barnyard");
            selectNewRegionComboBox.Items.Add("USA - Call Of Duty 3");
            selectNewRegionComboBox.Items.Add("USA - Cars");
            selectNewRegionComboBox.Items.Add("USA - Chicken Little - Ace In Action");
            selectNewRegionComboBox.Items.Add("JAP - Crayon Shinchan Saikyou Kazoku Kasukabe King");
            selectNewRegionComboBox.Items.Add("USA - Dragon Ball Z Budokai Tenkaichi 2");
            selectNewRegionComboBox.Items.Add("USA - Elebits");
            selectNewRegionComboBox.Items.Add("USA - Excite Truck");
            selectNewRegionComboBox.Items.Add("USA - GT Pro Series");
            selectNewRegionComboBox.Items.Add("USA - Happy Feet");
            selectNewRegionComboBox.Items.Add("USA - Ice Age 2 The Meltdown");
            selectNewRegionComboBox.Items.Add("USA - Metal Slug Anthology");
            selectNewRegionComboBox.Items.Add("USA - Monster 4x4 World Circuit");
            selectNewRegionComboBox.Items.Add("USA - Need for Speed Carbon");
            selectNewRegionComboBox.Items.Add("USA - Open Season");
            selectNewRegionComboBox.Items.Add("USA - Rampage Total Destruction");
            selectNewRegionComboBox.Items.Add("USA - Rayman Raving Rabbids");
            selectNewRegionComboBox.Items.Add("USA - Red Steel");
            selectNewRegionComboBox.Items.Add("USA - Sonic");
            selectNewRegionComboBox.Items.Add("USA - Splinter Cell Double Agent");
            selectNewRegionComboBox.Items.Add("USA - Spongebob Creature From The Krusty Krab");
            selectNewRegionComboBox.Items.Add("USA - Super Monkey Ball Banana Blitz");
            selectNewRegionComboBox.Items.Add("USA - Super Swing Golf");
            selectNewRegionComboBox.Items.Add("USA - The Ant Bully");
            selectNewRegionComboBox.Items.Add("USA - The Grim Adventures of Billy and Mandy");
            selectNewRegionComboBox.Items.Add("USA - The Legend Of Zelda Twilight Princess");
            selectNewRegionComboBox.Items.Add("USA - Tony Hawks Downhill Jam");
            selectNewRegionComboBox.Items.Add("USA - Trauma Center Second Opinion");
            selectNewRegionComboBox.Items.Add("USA - WarioWare Smooth Moves");
            selectNewRegionComboBox.Items.Add("USA - Play");
            selectNewRegionComboBox.Items.Add("USA - World Series of Poker Tournment of Champions 2007 Edition");
            /**selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            selectNewRegionComboBox.Items.Add("");
            **/
            selectNewRegionComboBox.SelectedIndex = 0;
            discInfoButton.Enabled = false;
            newRegionStringTextBox.Enabled = false;
            newRegionCodeTextBox.Enabled = false;
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 ab = new AboutBox1();

            ab.ShowDialog();
        }

        private void openISOToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Open file...";
            ofd.Filter = "ISO files (*.iso)|*.iso|All files (*.*)|*.*";
            ofd.Multiselect = false;

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //clear/reset stuff
                filenameTextBox.Clear();
                gameTitleTextBox.Clear();
                gameCodeTextBox.Clear();
                consoleIDAsciiTextBox.Clear();
                consoleIDTextBox.Clear();
                gameIDAsciiTextBox.Clear();
                gameIDTextBox.Clear();
                makerIDAsciiTextBox.Clear();
                makerIDTextBox.Clear();
                regionIDAsciiTextBox.Clear();
                regionIDTextBox.Clear();
                regionCodeHexTextBox.Clear();
                regionCodeTextBox.Clear();
                regionStringTextBox.Clear();
                offsetMagicWordTextBox.Clear();
                totalDiscPartitionsTextBox.Clear();
                mismatchTextBox.Clear();
                manualRegionCheckBox.Checked = false;
                selectNewRegionComboBox.SelectedIndex = 0;
                discInfoButton.Enabled = true;

                filenameTextBox.Text = ofd.FileName;
                
            }

            if (filenameTextBox.Text != "")
            {
                path = filenameTextBox.Text;
                filename = filenameTextBox.Text.Substring(filenameTextBox.Text.LastIndexOf('\\') + 1);
                patchISOToolStripMenuItem.Enabled = true;
                patchIsoButton.Enabled = true;

                loadfile();

            }



        }

        private void copyPartitionInfoToolStripMenuItem_Click(object sender, EventArgs e)
        {

            string iiString;
            iiString = "WiiSoFree Image Output" + "\r\n" + "Coded by: Shawn M. Crawford [sLeEpY]" + "\r\n"
                + "------------------------------------" + "\r\n" + "Filename: " + filenameTextBox.Text +
                "\r\n" + "Game Title: " + gameTitleTextBox.Text + "\r\n" + "Game Code: " + gameCodeTextBox.Text
                + " " + mismatchTextBox.Text + "\r\n" + "Console ID: " + consoleIDAsciiTextBox.Text + " "
                + consoleIDTextBox.Text + "\r\n" + "Game ID: " + gameIDAsciiTextBox.Text + " " +
                gameIDTextBox.Text + "\r\n" + "Maker ID: " + makerIDAsciiTextBox.Text + " " + makerIDTextBox.Text
                + "\r\n" + "Region ID: " + regionIDAsciiTextBox.Text + " " + regionIDTextBox.Text + "\r\n" +
                "Region Code: " + regionCodeHexTextBox.Text + " " + regionCodeTextBox.Text + "\r\n" + "Region String: " +
                regionStringTextBox.Text + "\r\n" + "Offset / Magic Word: " + offsetMagicWordTextBox.Text +
                "\r\n" + "Boot Settings: " + bootSettingByteTextBox.Text + " " + bootSettingTextBox.Text +
                "\r\n" + "Total Disc Partitions: " + totalDiscPartitionsTextBox.Text;
            Clipboard.SetText(iiString);
        }

        private void copyNewRegionStringToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (newRegionStringTextBox.SelectionLength == 0)
            {
                newRegionStringTextBox.SelectAll();
            }

            newRegionStringTextBox.Copy();
        }

        private void loadfile()
        {
            //1.Identify and output the region code
            string rc;

           //gonna need a try/catch here in case the file is in use
                FileStream fs1 = new FileStream(@path, FileMode.Open, FileAccess.Read);
                long offset = fs1.Seek(319491, SeekOrigin.Begin);   // Seek to 319491th byte in the file
                rc = fs1.ReadByte().ToString("X");
                //if length is single digit add a 0 ( 1 now is 01)
                if (rc.Length == 1)
                {
                    rc = "0" + rc;
                }
                regionCodeHexTextBox.Text = rc;
                fs1.Close();

            //int parse the string
            int rci = int.Parse(rc);
            //use the byte to identify the region
            switch (rci)
            {
                case 00:
                    //JAP NTSC
                    regionCodeTextBox.Text = "JAP NTSC";
                    break;

                case 01:
                    //USA NTSC
                    regionCodeTextBox.Text = "USA NTSC";
                    break;
                
                case 02:
                    //PAL
                    regionCodeTextBox.Text = "PAL";
                    break;

                default:
                    //error handling
                    regionCodeTextBox.Text = "????????";
                    break;

            }

            //2. get the region string
            //0x4E010 (319504d) - 0x4E01F (319519d)
            string rs;
            FileStream fs2 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset2 = fs2.Seek(319504, SeekOrigin.Begin);   // Seek to 319504th byte in the file

            rs = "0";

            int x = 0;
            while (x <= 15)
            {
            rs = fs2.ReadByte().ToString("X");
            //if length is single digit add a 0 ( 1 now is 01)
            if (rs.Length == 1)
            {
                rs = "0" + rs;
            }

            if (x > 0)
            {
                regionStringTextBox.Text += " " + rs;
            }
            else
            {
                regionStringTextBox.Text = rs;
            }

            x++;
            }
            
            fs2.Close();

            //3.Get the Console ID (Game Code) and auto/manual boot settings
            string cidToASCII_CID;
            string cid;
            FileStream fs3 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset3 = fs3.Seek(0, SeekOrigin.Begin);   // Seek to 0 (1st)byte in the file
            //read to hex
            cid = fs3.ReadByte().ToString("X");

            //convert the hex to the character letter
            cidToASCII_CID = "";

            if (cid != "0")
            {
                while (cid.Length > 0)
                {
                    // Use ToChar() to convert each ASCII value (two hex digits) to the actual character
                    cidToASCII_CID += System.Convert.ToChar(System.Convert.ToUInt32(cid.Substring(0, 2), 16)).ToString();
                    // Remove from the hex object the converted value
                    cid = cid.Substring(2, cid.Length - 2);
                }
            }
            if (cid == "0")
            {
                cidToASCII_CID = cid;
            }
            consoleIDAsciiTextBox.Text = cidToASCII_CID;//.ToString();
            bootSettingByteTextBox.Text = cidToASCII_CID;

            fs3.Close();
            
            if (cidToASCII_CID == "R")
            {
                consoleIDTextBox.Text = "Nintendo Wii (Revolution)";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "S")
            {
                consoleIDTextBox.Text = "Nintendo Wii";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "G")
            {
                consoleIDTextBox.Text = "Gamecube";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "H")
            {
                consoleIDTextBox.Text = "Wii Channel";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "F")
            {
                consoleIDTextBox.Text = "Virtual Console - NES";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "J")
            {
                consoleIDTextBox.Text = "Virtual Console - SNES";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "M")
            {
                consoleIDTextBox.Text = "Virtual Console - Genesis / Megadrive";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "T")
            {
                consoleIDTextBox.Text = "Virtual Console - TurboGraphx 16";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "N")
            {
                consoleIDTextBox.Text = "Virtual Console - N64";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "U")
            {
                consoleIDTextBox.Text = "Utility-disc(?)";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "D")
            {
                consoleIDTextBox.Text = "Gamecube Demo disc(?)";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "P")
            {
                consoleIDTextBox.Text = "Gamecube promotional disc(?)";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "0")
            {
                consoleIDTextBox.Text = "Diagnostic Disc";
                bootSettingTextBox.Text = "Auto";
            }
            else if (cidToASCII_CID == "1")
            {
                consoleIDTextBox.Text = "Diagnostic Disc";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "4")
            {
                consoleIDTextBox.Text = "Wii Backup Disc";
                bootSettingTextBox.Text = "Manual";
            }
            else if (cidToASCII_CID == "_")
            {
                consoleIDTextBox.Text = "WiiFit Chan installer ";
                bootSettingTextBox.Text = "Manual";
            }
            else
            {
                consoleIDTextBox.Text = "Unknown / Not Implemented Yet";
                bootSettingTextBox.Text = "Unknown";
            }
            

            //4.Get the Game ID (Game Code)
            string gidToASCII_GID;
            string gid;
            FileStream fs4 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset4 = fs4.Seek(1, SeekOrigin.Begin);   // Seek to 1 (2nd) byte in the file

            gid = "";
            x = 0;
            //this loop lets us grab byte 1 and byte 2
            while (x <= 1)
            {
            //read to hex
            gid = fs4.ReadByte().ToString("X");
            
            //convert the hex to the character letter
            gidToASCII_GID = "";
            while (gid.Length > 0)
            {
                // Use ToChar() to convert each ASCII value (two hex digits) to the actual character
                gidToASCII_GID += System.Convert.ToChar(System.Convert.ToUInt32(gid.Substring(0, 2), 16)).ToString();
                // Remove from the hex object the converted value
                gid = gid.Substring(2, gid.Length - 2);
            }
            gameIDAsciiTextBox.Text += gidToASCII_GID;//.ToString();
            x++;
            }
            fs4.Close();

            //5. Get the Region ID (Game Code)
            string ridToASCII_RID;
            string rid;
            FileStream fs5 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset5 = fs5.Seek(3, SeekOrigin.Begin);   // Seek to 3 (4th) byte in the file
            //read to hex
            rid = fs5.ReadByte().ToString("X");

            //convert the hex to the character letter
            ridToASCII_RID = "";
            while (rid.Length > 0)
            {
                // Use ToChar() to convert each ASCII value (two hex digits) to the actual character
                ridToASCII_RID += System.Convert.ToChar(System.Convert.ToUInt32(rid.Substring(0, 2), 16)).ToString();
                // Remove from the hex object the converted value
                rid = rid.Substring(2, rid.Length - 2);
            }
            regionIDAsciiTextBox.Text = ridToASCII_RID;//.ToString();

            fs5.Close();

            if (ridToASCII_RID == "E")
            {
                regionIDTextBox.Text = "USA";
            }
            else if (ridToASCII_RID == "P" || ridToASCII_RID == "Y")
            {
                regionIDTextBox.Text = "PAL";
            }
            else if (ridToASCII_RID == "J")
            {
                regionIDTextBox.Text = "JAP";
            }
            else if (ridToASCII_RID == "K")
            {
                regionIDTextBox.Text = "KOR";
            }
            else
            {
                regionIDTextBox.Text = "Unknown / Not Implemented Yet";
            }



            //6. Get the Maker ID (Make Code)
            string midToASCII_MID;
            string mid, mcComplete;
            FileStream fs6 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset6 = fs6.Seek(4, SeekOrigin.Begin);   // Seek to 4 (5th) byte in the file

            mid = "";
            midToASCII_MID = "";
            mcComplete = "";

            x = 0;
            //this loop lets us grab byte 1 and byte 2
            while (x <= 1)
            {
                //read to hex
                mid = fs6.ReadByte().ToString("X");

                //convert the hex to the character letter
                midToASCII_MID = "";
                while (mid.Length > 0)
                {
                    // Use ToChar() to convert each ASCII value (two hex digits) to the actual character
                    midToASCII_MID += System.Convert.ToChar(System.Convert.ToUInt32(mid.Substring(0, 2), 16)).ToString();
                    // Remove from the hex object the converted value
                    mid = mid.Substring(2, mid.Length - 2);
                }
                makerIDAsciiTextBox.Text += midToASCII_MID;
                
                mcComplete += midToASCII_MID;
                x++;
                
            }
            fs6.Close();

            //call the function in the class
            wiidiscdata wiidiscdata1 = new wiidiscdata();

            wiidiscdata1.GetMakerCode(mcComplete);
            makerIDTextBox.Text = wiidiscdata1.GetMakerCode(mcComplete);

            //7. Get the Game Code
            gameCodeTextBox.Text = consoleIDAsciiTextBox.Text + gameIDAsciiTextBox.Text + regionIDAsciiTextBox.Text + makerIDAsciiTextBox.Text;

            //8. Get number of Partitions
            string pi;
            FileStream fs7 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset7 = fs7.Seek(262144, SeekOrigin.Begin);   // Seek to 262144th byte in the file
            
            x = 0;
            //read four bytes to get the number of partitions
            while (x <= 3)
            {
                pi = fs7.ReadByte().ToString("X");
                if (pi.Length == 1)
                {
                    pi = "0" + pi;
                }
                totalDiscPartitionsTextBox.Text += pi;
                x++;
            }
            fs7.Close();
            
            
            
            //9.Get game title
            string gtToASCII_GT;
            string gt;
            FileStream fs8 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset8 = fs8.Seek(32, SeekOrigin.Begin);   // Seek to 32 byte in the file

            gt = "";
            gtToASCII_GT = "";
            //gtFull = "";

            x = 0;
            while (x <= 50)
            {
                //the following try / catch statements catch the error of reading the title, since
                //this title is variable depending on game it would crash or not read enough, 
                try
                {
                    //read to hex
                    gt = fs8.ReadByte().ToString("X");
                }
                catch
                {
                }
                //convert the hex to the character letter
                gtToASCII_GT = "";
                try
                {
                    while (gt.Length > 0)
                    {
                        // Use ToChar() to convert each ASCII value (two hex digits) to the actual character
                        gtToASCII_GT += System.Convert.ToChar(System.Convert.ToUInt32(gt.Substring(0, 2), 16)).ToString();
                        // Remove from the hex object the converted value
                        gt = gt.Substring(2, gt.Length - 2);
                    }
                }
                catch
                {
                }
                gameTitleTextBox.Text += gtToASCII_GT;

                x++;

            }
            fs8.Close();
            


            //10. Get offset / magic word?
            string ofmw;
            FileStream fs9 = new FileStream(@path, FileMode.Open, FileAccess.Read);
            long offset9 = fs9.Seek(24, SeekOrigin.Begin);   // Seek to 32 byte in the file

            ofmw = "";

            x = 0;
            //this loop lets us grab bytes 24 to 27
            while (x <= 3)
            {
                try
                {
                    //read to hex
                    ofmw = fs9.ReadByte().ToString("X");
                }
                catch
                {
                }
                //output the hex magic word
                offsetMagicWordTextBox.Text += ofmw;

                x++;

            }
            fs9.Close();


            //11.check if iso has been patched / game code mismatch
            string rciString;

            rciString = rci.ToString();

            if (ridToASCII_RID == "E" && rciString == "1")
            {
                //regionIDTextBox.Text = "USA";
                mismatchTextBox.Text = "Unpatched";
            }
            else if (ridToASCII_RID == "P" && rciString == "2" || ridToASCII_RID == "Y" && rciString == "2")
            {
                mismatchTextBox.Text = "Unpatched";
            }
            else if (ridToASCII_RID == "J" && rciString == "0")
            {
                mismatchTextBox.Text = "Unpatched";
            }
            else if (ridToASCII_RID == "K")
            {
                mismatchTextBox.Text = "Korean is not supported yet.";
            }
            else
            {
                mismatchTextBox.Text = "Region ID & Region Code Mismatch / Patched iso?";
            }

            //TODO fs10
            gameIDTextBox.Text = "Not Implemented Yet";

        }

        private void manualRegionCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (manualRegionCheckBox.Checked)
            {
                newRegionStringTextBox.Enabled = true;
                newRegionCodeTextBox.Enabled = true;
            }
            else
            {
                newRegionStringTextBox.Enabled = false;
                newRegionCodeTextBox.Enabled = false;
            }
        }

        private void patchIsoButton_Click(object sender, EventArgs e)
        {
            int errorCounterInt = 0;
            //1. write the new region string
            //0x4E010 (319504d) - 0x4E01F (319519d)
            string regionPatchValueString, regionPatchValueString2;

            regionPatchValueString = newRegionStringTextBox.Text;
            //get rid of spaces
            regionPatchValueString2 = regionPatchValueString.Replace(" ", "");


            //setup arrays
            string[] rpvs = new string[32];
            byte[] rpvsb = new byte[32];
            int[] rpvsd = new int[32];
            string[] rpvs_final = new string[32];

            //split it up into twos
            rpvs[0] = regionPatchValueString2[0].ToString() + regionPatchValueString2[1].ToString();
            rpvs[1] = regionPatchValueString2[2].ToString() + regionPatchValueString2[3].ToString();
            rpvs[2] = regionPatchValueString2[4].ToString() + regionPatchValueString2[5].ToString();
            rpvs[3] = regionPatchValueString2[6].ToString() + regionPatchValueString2[7].ToString();
            rpvs[4] = regionPatchValueString2[8].ToString() + regionPatchValueString2[9].ToString();
            rpvs[5] = regionPatchValueString2[10].ToString() + regionPatchValueString2[11].ToString();
            rpvs[6] = regionPatchValueString2[12].ToString() + regionPatchValueString2[13].ToString();
            rpvs[7] = regionPatchValueString2[14].ToString() + regionPatchValueString2[15].ToString();
            rpvs[8] = regionPatchValueString2[16].ToString() + regionPatchValueString2[17].ToString();
            rpvs[9] = regionPatchValueString2[18].ToString() + regionPatchValueString2[19].ToString();
            rpvs[10] = regionPatchValueString2[20].ToString() + regionPatchValueString2[21].ToString();
            rpvs[11] = regionPatchValueString2[22].ToString() + regionPatchValueString2[23].ToString();
            rpvs[12] = regionPatchValueString2[24].ToString() + regionPatchValueString2[25].ToString();
            rpvs[13] = regionPatchValueString2[26].ToString() + regionPatchValueString2[27].ToString();
            rpvs[14] = regionPatchValueString2[28].ToString() + regionPatchValueString2[29].ToString();
            rpvs[15] = regionPatchValueString2[30].ToString() + regionPatchValueString2[31].ToString();
                    
            //convert the chars to int32, then to string, then byte again
            int q = 0;
            while (q <= 15)
            {
                rpvsd[q] = int.Parse(rpvs[q], System.Globalization.NumberStyles.HexNumber);
                rpvs_final[q] = rpvsd[q].ToString();
                rpvsb[q] = byte.Parse(rpvs_final[q]);
                q++;
            }


            FileStream fs11 = new FileStream(@path, FileMode.Open, FileAccess.Write);
            long offset11 = fs11.Seek(319504, SeekOrigin.Begin);   // Seek to 319491th byte in the file
            //this is converting to hex before it writes
            q = 0;
            while (q <= 15)
            {
                fs11.WriteByte(rpvsb[q]);
            q++;
            }
            
            fs11.Close();

            string newRegionCodeString;
            newRegionCodeString = "01"; //default usa
            //2.Write the new region code
            if (newRegionCodeTextBox.Text == "00")
            {
                newRegionCodeString = "00"; //jap
            }
            else if (newRegionCodeTextBox.Text == "01")
            {
                newRegionCodeString = "01"; //usa
            }
            else if (newRegionCodeTextBox.Text == "02")
            {
                newRegionCodeString = "02"; //pal
            }
            else
            {
                MessageBox.Show("Something went wrong with regioncode conversion 00/01/02!", "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                errorCounterInt = 1;
            }

            string[] nrcs = new string[2];
            byte[] nrcsb = new byte[2];
            int[] nrcsd = new int[2];
            string[] nrcss_final = new string[2];

            nrcs[0] = newRegionCodeString;

            nrcsd[0] = int.Parse(nrcs[0], System.Globalization.NumberStyles.HexNumber);
            nrcss_final[0] = nrcsd[0].ToString();
            nrcsb[0] = byte.Parse(nrcss_final[0]);

                FileStream fs12 = new FileStream(@path, FileMode.Open, FileAccess.Write);
                long offset12 = fs12.Seek(319491, SeekOrigin.Begin);   // Seek to 319491th byte in the file
                //this is converting to hex before it writes
                fs12.WriteByte(nrcsb[0]);
            
                fs12.Close();


            //3.Write boot setting
            string bootSetting = "0";
            byte bootSettingByte;

            if (changeBootSettingCheckBox.Checked)
            {

                if (changeBootSettingComboBox.SelectedIndex == 0)
                {
                    bootSetting = "82";
                }
                else if (changeBootSettingComboBox.SelectedIndex == 1)
                {
                    bootSetting = "00";
                }

                bootSettingByte = byte.Parse(bootSetting);

                FileStream fs13 = new FileStream(@path, FileMode.Open, FileAccess.Write);
                long offset13 = fs13.Seek(0, SeekOrigin.Begin);   // Seek to 1st byte in the file
                //this is converting to hex before it writes

                fs13.WriteByte(bootSettingByte);
            
                fs13.Close();
            }


            //this should remove the update partition
            if (disableUpdatePartCheckBox.Checked)
            {
                //this is now a blind patch, it just finds the data at 
                //original
                //000040020 00 01 40 00 00 00 00 01
                //modifies to
                //000040020 00 00 00 00 00 00 00 00

                int x;



                string[] dups = new string[8];
                byte[] dupsb = new byte[8];
                int[] dupsd = new int[8];
                string[] dupss_final = new string[8];

                dups[0] = "00";
                dups[1] = "00";
                dups[2] = "00";
                dups[3] = "00";
                dups[4] = "00";
                dups[5] = "00";
                dups[6] = "00";
                dups[7] = "00";

                x = 0;
                while (x <= 7)
                {
                    dupsd[x] = int.Parse(dups[x], System.Globalization.NumberStyles.HexNumber);
                    dupss_final[x] = dupsd[x].ToString();
                    dupsb[x] = byte.Parse(dupss_final[x]);
                    x++;
                }


                FileStream fs14 = new FileStream(@path, FileMode.Open, FileAccess.Write);
                long offset14 = fs14.Seek(262176, SeekOrigin.Begin);   // Seek to 262176th byte in the file

                x = 0;
                while (x <= 7)
                {
                    fs14.WriteByte(dupsb[0]);
                    x++;
                }

                fs14.Close();
            }


            if (errorCounterInt == 0)
            {
                MessageBox.Show("Iso Successfully Patched! Re-open the iso to see the changes.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            if (errorCounterInt == 1)
            {
                MessageBox.Show("Something failed in the patching process!", "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void discInfoButton_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();

            f2.filenameF2TextBoxValue = filenameTextBox.Text;

            f2.ShowDialog();
            
        }

        private void openWADToolStripMenuItem_Click(object sender, EventArgs e)
        {
                wadForm wf = new wadForm();
                wf.ShowDialog();  
        }

    }
}
